package cn.ztuo.bitrade.service;

import cn.ztuo.bitrade.constant.PageModel;
import cn.ztuo.bitrade.dao.ContractPriceControlMapper;
import cn.ztuo.bitrade.entity.ContractOrder;
import cn.ztuo.bitrade.entity.ContractPositionForce;
import cn.ztuo.bitrade.entity.ContractPriceControl;
import cn.ztuo.bitrade.pagination.Criteria;
import cn.ztuo.bitrade.pagination.Restrictions;
import cn.ztuo.bitrade.util.BeanUtils;
import cn.ztuo.bitrade.util.DateUtil;
import cn.ztuo.bitrade.vo.contractPriceControlVo.ContractPriceControlAddReqVo;
import cn.ztuo.bitrade.vo.contractPriceControlVo.ContractPriceControlFindReqVo;
import com.alibaba.fastjson.JSON;
import org.hibernate.criterion.*;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.text.ParseException;
import java.util.*;

@Service
public class ContractPriceControlService {
    @Autowired
    private ContractPriceControlMapper mapper;

    @Transactional(rollbackFor = Exception.class)
    public ContractPriceControl saveAndFlush(ContractPriceControlAddReqVo reqVo) {
        long seconds = reqVo.getSeconds();
        ContractPriceControl contractPriceControl = new ContractPriceControl();
//        BeanUtils.copyProperties(reqVo, contractPriceControl);

        contractPriceControl.setId(reqVo.getId());
        contractPriceControl.setSymbol(reqVo.getSymbol());
        contractPriceControl.setPrice(reqVo.getPrice());
        contractPriceControl.setSeconds(reqVo.getSeconds());
        contractPriceControl.setStatus(reqVo.getStatus());
        contractPriceControl.setStartTime(reqVo.getStartTimeDate());
        contractPriceControl.setEndTime(reqVo.getEndTimeDate());
        if (contractPriceControl.getStartTime() == null) {
            contractPriceControl.setStartTime(new Date());
        }
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(contractPriceControl.getStartTime());
        calendar.add(Calendar.SECOND, (int) seconds); //把日期往后增加一天,整数  往后推,负数往前移动
        Date endTime = calendar.getTime(); //这个时间就是日期往后推一天的结果
        contractPriceControl.setEndTime(endTime);
        if(contractPriceControl.getId()==null){
            contractPriceControl.setCreateTime(new Date());
        }else{
            Date createTime = mapper.getById(contractPriceControl.getId()).getCreateTime();
            contractPriceControl.setCreateTime(createTime==null?new Date():createTime);
        }
        contractPriceControl.setUpdateTime(new Date());
        return mapper.saveAndFlush(contractPriceControl);
    }

    @Transactional(rollbackFor = Exception.class)
    public ContractPriceControl saveAndFlush(ContractPriceControl contractPriceControl) {
        return mapper.saveAndFlush(contractPriceControl);
    }

    public Boolean isTimeOk(ContractPriceControlAddReqVo reqVo) throws ParseException {
        String startTimeStr = reqVo.getStartTime().replace("T", " ").replace("000.Z", "");
        Date startTime = DateUtil.datehhmmss(startTimeStr);
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(startTime);
        calendar.add(Calendar.SECOND, (int) reqVo.getSeconds().longValue()); //把日期往后增加一天,整数  往后推,负数往前移动
        Date endTime = calendar.getTime(); //这个时间就是日期往后推一天的结果
        reqVo.setEndTimeDate(endTime);

        int count = mapper.counts(reqVo.getId(),reqVo.getSymbol(),reqVo.getStartTimeDate(),reqVo.getEndTimeDate());
        if (count > 0) {
            return false;
        }
        return true;
    }

    public void delete(ContractPriceControl contractPriceControl) {
        mapper.delete(contractPriceControl);
    }

    public ContractPriceControl get(Long id) {
        return mapper.getById(id);
    }

    public Page<ContractPriceControl> findAllByPage(ContractPriceControlFindReqVo reqVo) {
        ContractPriceControl contractPriceControl = new ContractPriceControl();
        BeanUtils.copyProperties(reqVo, contractPriceControl);

        Sort orders = new Sort(new Sort.Order(Sort.Direction.DESC, "startTime"));
        //从第一条开始查
        if (reqVo.getPageNo() == null || reqVo.getPageNo() == 0) {
            reqVo.setPageNo(1);
        }
        if (reqVo.getPageSize() == null || reqVo.getPageSize() == 0) {
            reqVo.setPageSize(10);
        }
        PageRequest pageRequest = new PageRequest(reqVo.getPageNo() - 1, reqVo.getPageSize(), orders);
        Criteria<ContractPriceControl> specification = new Criteria<ContractPriceControl>();

        specification.add(Restrictions.eq("symbol", contractPriceControl.getSymbol(), true));
        specification.add(Restrictions.gte("startTime", contractPriceControl.getStartTime(), true));
        specification.add(Restrictions.lte("endTime", contractPriceControl.getEndTime(), true));
        specification.add(Restrictions.eq("status", contractPriceControl.getStatus(), true));

        return mapper.findAll(specification, pageRequest);
    }

    public List<ContractPriceControl> findAll(ContractPriceControlFindReqVo reqVo) {
        Criteria<ContractPriceControl> specification = new Criteria<ContractPriceControl>();
        specification.add(Restrictions.eq("symbol", reqVo.getSymbol(), true));
        specification.add(Restrictions.gte("startTime", reqVo.getStartTime(), true));
        specification.add(Restrictions.lte("endTime", reqVo.getEndTime(), true));
        specification.add(Restrictions.eq("status", reqVo.getStatus(), true));
        specification.sort("startTime.desc");
        return mapper.findAll(specification);
    }

    public List<ContractPriceControl> findAllCanable(ContractPriceControlFindReqVo reqVo) {
        Criteria<ContractPriceControl> specification = new Criteria<ContractPriceControl>();
        specification.add(Restrictions.eq("symbol", reqVo.getSymbol(), true));
        specification.add(Restrictions.gte("endTime", reqVo.getEndTime(), true));
        specification.add(Restrictions.or(Restrictions.eq("status", 0, true)
                , Restrictions.eq("status", "1", true)
                , Restrictions.eq("status", "2", true)));
        specification.sort("startTime.desc");
        return mapper.findAll(specification);
    }
}
